
                /*********************************************
                **                                          **
                **                                          **
                **              split CommL                 **
                **                                          **
                **                                          **
                *********************************************/
                /*********************************************
                **                                          **
                **         Author Jean-Marc Adamo           **
                **       Copyright (C) 1997-2008 JMA        **
                *********************************************/



/*
** execute with 6 processes
*/


#include "arch.h"
#include "A.utilities"

//user program

Coll_id cid1, cid2, cid3;

//on most homogenous systems, explicit setting 
//wont be necessary (try commenting the
//setting lines, you should get the same values
//for cid1 and cid2).
void init(int, char **){
   cid1.set();
   cid2.set();
   fprintf(Sdf::trace, "node%d: cid1=%d, cid2=%d, cid3=%d\n",
           Sdf::PROC_ID, cid1.get(), cid2.get(), cid3.get());
   fflush(Sdf::trace);
}

class Root_proc: public Thread{

   public:

        Root_proc()
                : Thread((Tmf0_ptr)&Root_proc::body){}

        void body(){

            fprintf(Sdf::trace, "node %d, in Root_proc::starts\n", Sdf::PROC_ID);
            fflush(Sdf::trace);

            Group *Group_world = Sdf::COMML_WORLD;
            Group *grp_incl1;

            int rank1s[3] = {1, 3, 5};
            grp_incl1 = Sdf::incl(Group_world, 3, rank1s);

            int grp_incl1_size = grp_incl1->size();
            int grp_incl1_rank = grp_incl1->rank();

            int rank2s[3] = {0, 2, 4};
            Group *grp_incl2 = Sdf::incl(Group_world, 3, rank2s);

            int grp_incl2_size = grp_incl2->size();
            int grp_incl2_rank = grp_incl2->rank();

            Group *grp_add = Sdf::add(grp_incl1, grp_incl2);

            int grp_add_size = grp_add->size();
            int grp_add_rank = grp_add->rank();

            fprintf(Sdf::trace, "node %d, 1size=%d, 2size=%d, 3size=%d, 1rank=%d, 2rank=%d, 3rank=%d\n", 
                    Sdf::PROC_ID, 
                    grp_incl1_size, grp_incl2_size, grp_add_size,
                    grp_incl1_rank, grp_incl2_rank, grp_add_rank);
            fflush(Sdf::trace);

            CommL *comm = grp_add->commit(cid1, Sdf::COMML_WORLD);

            int colour;
            int key;
            if(grp_add_rank == 0 || grp_add_rank == 1){
               colour = 0;
               if(grp_add_rank == 0)
                 key = 1;
               else
                 key = 0;
            }else if(grp_add_rank == 2 || grp_add_rank == 3){
               colour = Sdf::UNDEFINED;
               if(grp_add_rank == 2)
                 key = 1;
               else
                 key = 0;
            }else{
               colour = 2;
               if(grp_add_rank == 4)
                 key = 1;
               else
                 key = 0;
            }
            
            CommL **newcomm = comm->split(cid2, 2, colour, key);

            int *ranks;

            ranks = newcomm[0]->get_world_ranks();

            fprintf(Sdf::trace, "node %d, Sdf::UNDEFINED=%d, newcomm=%d, ranks[0]=%d, ranks[1]=%d\n", 
                    Sdf::PROC_ID, Sdf::UNDEFINED, newcomm,
                    ranks[0], ranks[1]);
            fflush(Sdf::trace);

            ranks = newcomm[1]->get_world_ranks();

            fprintf(Sdf::trace, "node %d, Sdf::UNDEFINED=%d, newcomm=%d, ranks[0]=%d, ranks[1]=%d\n", 
                    Sdf::PROC_ID, Sdf::UNDEFINED, newcomm,
                    ranks[0], ranks[1]);
            fflush(Sdf::trace);

            delete comm;    //grp_add and comm coincide
            delete newcomm[0], delete newcomm[1];
            delete []newcomm;
            delete grp_incl1;
            delete grp_incl2;

            fprintf(Sdf::trace, "node %d, in Root_proc::finishes\n", Sdf::PROC_ID);
            fflush(Sdf::trace);
        }
};
//end of user program

MAIN(Root_proc, init, Sdf::empty, Sdf::empty)
